/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.javahispano.javacup.tacticas_aceptadas.Elias;

import java.util.LinkedList;

import org.javahispano.javacup.modelo.*;
import java.util.List;

public class TacticaNottingan implements Tactica {

    Posicion alineacion1[] = new Posicion[]{
        new Posicion(0.951048951048951, -49.411764705882355),
        new Posicion(-18.307692307692307, -30.16968325791855),
        new Posicion(-5.468531468531468, -29.457013574660635),
        new Posicion(16.88111888111888, -30.407239819004527),
        new Posicion(3.3286713286713288, -29.457013574660635),
        new Posicion(14.265734265734267, -4.513574660633484),
        new Posicion(-15.692307692307693, -3.800904977375566),
        new Posicion(-0.951048951048951, -11.165158371040723),
        new Posicion(-16.88111888111888, 28.031674208144796),
        new Posicion(-1.6643356643356644, 19.004524886877828),
        new Posicion(12.125874125874127, 27.556561085972852)
    };
    Posicion alineacion2[] = new Posicion[]{
        new Posicion(0.2595419847328244, -50.41044776119403),
        new Posicion(-11.16030534351145, -31.082089552238806),
        new Posicion(11.16030534351145, -31.6044776119403),
        new Posicion(27.251908396946565, -27.94776119402985),
        new Posicion(-29.84732824427481, -26.902985074626866),
        new Posicion(8.564885496183205, -7.574626865671642),
        new Posicion(-10.641221374045802, -7.052238805970149),
        new Posicion(27.251908396946565, 4.440298507462686),
        new Posicion(-29.32824427480916, 3.3955223880597014),
        new Posicion(-0.2595419847328244, 19.067164179104477),
        new Posicion(-0.2595419847328244, 35.78358208955224)
    };
    Posicion alineacion3[] = new Posicion[]{
        new Posicion(0.2595419847328244, -50.41044776119403),
        new Posicion(-18.307692307692307, -32.30769230769231),
        new Posicion(-5.706293706293707, -32.07013574660634),
        new Posicion(16.88111888111888, -32.782805429864254),
        new Posicion(5.468531468531468, -32.07013574660634),
        new Posicion(11.412587412587413, -1.4253393665158371),
        new Posicion(-13.076923076923078, -0.9502262443438915),
        new Posicion(-0.7132867132867133, 10.214932126696834),
        new Posicion(-12.363636363636363, 32.30769230769231),
        new Posicion(-1.4265734265734267, 24.943438914027148),
        new Posicion(10.461538461538462, 31.357466063348415)
    };
    Posicion alineacion4[] = new Posicion[]{
        new Posicion(0.2595419847328244, -50.41044776119403),
        new Posicion(-8.797202797202797, -30.6447963800905),
        new Posicion(7.846153846153847, -31.83257918552036),
        new Posicion(21.16083916083916, -28.744343891402718),
        new Posicion(-23.776223776223777, -28.744343891402718),
        new Posicion(11.16030534351145, -1.3059701492537314),
        new Posicion(-10.641221374045802, -0.7835820895522387),
        new Posicion(-23.3006993006993, 31.357466063348415),
        new Posicion(-5.944055944055944, 29.457013574660635),
        new Posicion(5.944055944055944, 29.21945701357466),
        new Posicion(21.3986013986014, 29.457013574660635)
    };
    Posicion alineacion5[] = new Posicion[]{
        new Posicion(0.2595419847328244, -50.41044776119403),
        new Posicion(-7.846153846153847, -34.920814479638004),
        new Posicion(0.951048951048951, -34.68325791855204),
        new Posicion(12.125874125874127, -34.44570135746606),
        new Posicion(-19.496503496503497, -18.766968325791854),
        new Posicion(15.692307692307693, -17.104072398190045),
        new Posicion(-1.188811188811189, -16.866515837104075),
        new Posicion(-23.618320610687025, -0.7835820895522387),
        new Posicion(5.969465648854961, -5.485074626865671),
        new Posicion(0.2595419847328244, -0.26119402985074625),
        new Posicion(23.776223776223777, -0.7126696832579186)
    };
    Posicion alineacion6[] = new Posicion[]{
        new Posicion(0.2595419847328244, -50.41044776119403),
        new Posicion(-11.174825174825173, -33.257918552036195),
        new Posicion(9.272727272727272, -33.257918552036195),
        new Posicion(21.3986013986014, -33.49547511312217),
        new Posicion(-22.825174825174827, -18.529411764705884),
        new Posicion(17.594405594405593, -19.004524886877828),
        new Posicion(-0.4755244755244755, -17.816742081447966),
        new Posicion(-23.618320610687025, -0.7835820895522387),
        new Posicion(6.4885496183206115, -6.529850746268657),
        new Posicion(-6.4885496183206115, -6.529850746268657),
        new Posicion(22.580152671755727, -1.3059701492537314)
    };
    Posicion alineacion7[] = new Posicion[]{
        new Posicion(0.2595419847328244, -50.41044776119403),
        new Posicion(-10.461538461538462, -39.90950226244344),
        new Posicion(0.951048951048951, -39.90950226244344),
        new Posicion(12.601398601398602, -39.43438914027149),
        new Posicion(22.825174825174827, -19.95475113122172),
        new Posicion(-6.419580419580419, -23.755656108597286),
        new Posicion(-20.923076923076923, -19.717194570135746),
        new Posicion(8.55944055944056, -25.656108597285066),
        new Posicion(-7.608391608391608, -7.126696832579185),
        new Posicion(1.4265734265734267, -18.529411764705884),
        new Posicion(8.083916083916083, -6.651583710407239)
    };

    @Override
    public Posicion[] getPosicionSaca(SituacionPartido sp) {
        return alineacion5;
    }

    @Override
    public Posicion[] getPosicionRecive(SituacionPartido sp) {
        return alineacion6;
    }
    TacticaNottinganDetalle detalle = new TacticaNottinganDetalle();

    @Override
    public TacticaDetalle getDetalle() {
        return detalle;
    }

    public void despeje_defensa(SituacionPartido sp) {
        for (int i = 1; i < 5; i++) {
            //Si el balon esta a menos de 15 de la defensa y del portero
            if (sp.misJugadores()[i].distancia(sp.balon()) < 15) {
                //comandos.add(new ComandoGolpearBalon(i, new Posicion(0,0),1,40 ));
                int riv_izda = 0, riv_centro = 0, riv_dcha = 0;
                for (int a = 0; a < 11; a++) {
                    if ((sp.rivales()[a].getY() > -20)&& (sp.rivales()[a].getY()<10) && (sp.rivales()[a].getX() < -11)) {
                        riv_izda++;
                    }
                    if ((sp.rivales()[a].getY() > -20)&& (sp.rivales()[a].getY()<10) && (sp.rivales()[a].getX() > 11)) {
                        riv_dcha++;
                    }
                    if ((sp.rivales()[a].getY() > -20)&& (sp.rivales()[a].getY()<10) && (sp.rivales()[a].getX() > -11)&& (sp.rivales()[a].getX() < 11)) {
                        riv_centro++;
                    }
                }
                //Buscamos la zona con menos rivales
                if (riv_izda < riv_dcha) {
                    if (riv_izda < riv_centro) { //tira a la izda
                        if (sp.misJugadores()[i].distancia(sp.misJugadores()[6]) > 20) //Despeja lejos
                        {
                            desmarca_centrales(sp);
                            comandos.add(new ComandoGolpearBalon(i, sp.misJugadores()[6], 1, 40));
                        } else //Despeja pasando cerca
                        {
                            desmarca_centrales(sp);
                            comandos.add(new ComandoGolpearBalon(i, sp.misJugadores()[6], 1, false));
                        }
                    } else { //tira al centro
                        if (sp.misJugadores()[i].distancia(sp.misJugadores()[7]) > 20) {
                            desmarca_centrales(sp);
                            comandos.add(new ComandoGolpearBalon(i, sp.misJugadores()[7], 1, 40));
                        } else {
                            desmarca_centrales(sp);
                            comandos.add(new ComandoGolpearBalon(i, sp.misJugadores()[7], 1, false));
                        }
                    }
                } else { //tira a la dcha
                    if (sp.misJugadores()[i].distancia(sp.misJugadores()[5]) > 20) {
                        desmarca_centrales(sp);
                        comandos.add(new ComandoGolpearBalon(i, sp.misJugadores()[5], 1, 40));
                    } else {
                        desmarca_centrales(sp);
                        comandos.add(new ComandoGolpearBalon(i, sp.misJugadores()[5], 1, false));
                    }
                }
            }

        }
    }

     public void desmarca_centrales(SituacionPartido sp){

         for (int i = 1; i < 11; i++) {
            //izda
            //if ((sp.rivales()[i].getY() > -25) && (sp.rivales()[i].getY() < 25)) {
            if ((sp.rivales()[i].getY() > -25) && (sp.rivales()[i].getY() < 25) && (sp.rivales()[i].getX() < -11)) {
                comandos.add(new ComandoIrA(6,new Posicion(sp.rivales()[i].getX()+3  ,sp.rivales()[i].getY())));
            }
            if ((sp.rivales()[i].getY() > -25) && (sp.rivales()[i].getY() < 25) && (sp.rivales()[i].getX() > -11) && (sp.rivales()[i].getX() < 11)) {
                comandos.add(new ComandoIrA(7,new Posicion(sp.rivales()[i].getX()+3  ,sp.rivales()[i].getY())));
            }
            if ((sp.rivales()[i].getY() > -25) && (sp.rivales()[i].getY() < 25) && (sp.rivales()[i].getX() > 11)) {
                comandos.add(new ComandoIrA(5,new Posicion(sp.rivales()[i].getX()-3  ,sp.rivales()[i].getY())));
            }
    }
    }

    public void despeje_portero(SituacionPartido sp){
        int riv_izda = 0,riv_centro=0, riv_dcha=0;
    	if(sp.misJugadores()[0].distancia(sp.balon())<3){
                for (int a = 0; a < 11; a++) {
                    if ((sp.rivales()[a].getY() > -20)&& (sp.rivales()[a].getY()<10) && (sp.rivales()[a].getX() < -11)) {
                        riv_izda++;
                    }
                    if ((sp.rivales()[a].getY() > -20)&& (sp.rivales()[a].getY()<10) && (sp.rivales()[a].getX() > 11)) {
                        riv_dcha++;
                    }
                    if ((sp.rivales()[a].getY() > -20)&& (sp.rivales()[a].getY()<10) && (sp.rivales()[a].getX() > -11)&& (sp.rivales()[a].getX() < 11)) {
                        riv_centro++;
                    }
                }
    	}//Buscamos la zona con menos rivales
                if (riv_izda < riv_dcha){
                    if (riv_izda<riv_centro){ //tira a la izda
                            comandos.add(new ComandoGolpearBalon(0, sp.misJugadores()[6],1,40 ));
                    }else{ //tira al centro
                            comandos.add(new ComandoGolpearBalon(0, sp.misJugadores()[7],1,40 ));
                    }
                }else{ //tira a la dcha
                        comandos.add(new ComandoGolpearBalon(0, sp.misJugadores()[5],1,40 ));
                }
    }

    public void defensa(SituacionPartido sp) {

        for (int i = 1; i < 11; i++) {

            //izda
            if ((sp.rivales()[i].getY() < -25) && (sp.rivales()[i].getX() < -10)) {
                comandos.add(new ComandoIrA(1, sp.rivales()[i]));
            }
            //dcha
            if ((sp.rivales()[i].getY() < -25) && (sp.rivales()[i].getX() > 10)) {
                comandos.add(new ComandoIrA(3, sp.rivales()[i]));
            }
            //centro izda
            if ((sp.rivales()[i].getY() < -25) && (sp.rivales()[i].getX() > -10) && (sp.rivales()[i].getX() < 0)) {
                comandos.add(new ComandoIrA(2, sp.rivales()[i]));

            }
            //centro dcha
            if ((sp.rivales()[i].getY() < -25) && (sp.rivales()[i].getX() < 10) && (sp.rivales()[i].getX() > 0)) {
                comandos.add(new ComandoIrA(4, sp.rivales()[i]));
            }
        }
    }
    LinkedList<Comando> comandos = new LinkedList<Comando>();

    @Override
    public List<Comando> ejecutar(SituacionPartido sp) {
        //vacia la lista de comandos
        comandos.clear();
        //si voy perdiendo o empatando
        if (sp.golesPropios() <= sp.golesRival()) {
            //cada jugador ubicarse segun alineacion1
            for (int i = 0; i < 11; i++) {
                comandos.add(new ComandoIrA(i, alineacion3[i]));
                defensa(sp);
                if((sp.balon().getY() > -25) )
                desmarca_centrales(sp);
            }
        } else {//sino, osea que voy ganando
            //cada jugador ubicarse segun alineacion2
            for (int i = 0; i < 11; i++) {
                comandos.add(new ComandoIrA(i, alineacion1[i]));
                defensa(sp);
                if((sp.balon().getY() > -25))
                desmarca_centrales(sp);
            }
        }

        //Centra portero
        if (sp.balon().getX() < 0) {
            comandos.add(new ComandoIrA(0, new Posicion(-1.5, -50.41)));
        } else if (sp.balon().getX() > 0) {
            comandos.add(new ComandoIrA(0, new Posicion(+1.5, -50.41)));
        } else if (sp.balon().getX() == 0) {
            comandos.add(new ComandoIrA(0, new Posicion(0, -50.41)));
        }


        //obtiene el indice del jugador mas cercano al balon
        int indMasCercano = sp.balon().indiceMasCercano(sp.misJugadores());
        //el jugador mas cercano sigue al balon
        comandos.add(new ComandoIrA(indMasCercano, sp.balon()));

        //obtiene un arreglo con los indices de los jugadores que pueden rematar
        int rematan[] = sp.puedenRematar();
        //recorre los jugadores que pueden rematar
        for (int i : rematan) {
            //obtiene los jugadores mas cercanos, al jugador que puede rematar
            int[] cercanos = sp.misJugadores()[i].indicesMasCercanos(sp.misJugadores());
            //obtiene los jugadores mas cercanos, al jugador que puede rematar
            int cercanorival = sp.balon().indiceMasCercano(sp.rivales());
            //encontro un pase en falso
            boolean pase = false;
            boolean alto;
            double fuerte;
            //recorre los jugadores desde el mas lejano al mas cercano
            for (int j = 1; !pase && j < cercanos.length; j++) {
                //si el jugador es distinto al jugador que remata y el jugador esta mas adelantado
                if (sp.misJugadores()[i].getY() < sp.misJugadores()[cercanos[j]].getY()) {
                    //dar pase al jugador mas cercano que este en posicion mas ofensiva
                    if (sp.misJugadores()[i].distancia(sp.misJugadores()[cercanos[j]]) > 30) {
                        fuerte=1;
                        alto = true;
                    } else if ((sp.balon().getY()<40)&&sp.misJugadores()[i].distancia(sp.rivales()[cercanorival]) < sp.misJugadores()[i].distancia(sp.misJugadores()[cercanos[j]])){
                        fuerte=0.75;
                        if(sp.balon().getY()<40)
                        alto = true;
                        else
                            alto=false;
                    }else if (sp.misJugadores()[i].distancia(sp.misJugadores()[cercanos[j]]) < 30 && sp.misJugadores()[i].distancia(sp.misJugadores()[cercanos[j]]) > 12){
                        fuerte=0.6;
                        alto = false;
                    }
                    else {
                        fuerte=0.5;
                        alto = false;
                    }

                    //hay que hacerlo mas gradual
                    comandos.add(new ComandoGolpearBalon(i, sp.misJugadores()[cercanos[j]], fuerte, alto));
                    //encontro un pase por lo menos
                    pase = true;
                }
            }
            //si no encontro ningun pase
            if (!pase) {
                //da pase hacia el jugador mas cercano
                if (sp.misJugadores()[i].distancia(sp.misJugadores()[cercanos[1]]) > 20) {
                    fuerte=1;
                    alto = true;
                } else {
                    fuerte=0.5;
                    alto = false;
                }
                comandos.add(new ComandoGolpearBalon(i, sp.misJugadores()[cercanos[1]], fuerte, alto));
            }
            //si el jugador que remata esta a menos de 30 metros del arco rival -> remata al arco

            if (sp.misJugadores()[i].distancia(Constantes.centroArcoSup) < 30) {
                if (sp.misJugadores()[i].distancia(Constantes.centroArcoSup) < 25) {
                    comandos.add(new ComandoGolpearBalon(i, Constantes.centroArcoSup, 1, 10));
                } else {
                    comandos.add(new ComandoGolpearBalon(i, Constantes.centroArcoSup, 1, 40));
                }
            }

        }

        despeje_defensa(sp);
        despeje_portero(sp);
        //retorna la lista de comandos.
        return comandos;
    }
}
